package com.lld.im.service.group.service;

import com.ecode.imecode.pack.message.ChartMessageAckPack;
import com.lld.im.common.ResponseVO;
import com.lld.im.common.enums.commond.GroupEventCommand;
import com.lld.im.common.enums.commond.MessageCommand;
import com.lld.im.common.model.message.GroupMessageContent;
import com.lld.im.service.message.server.CheckChartServer;
import com.lld.im.service.message.server.MessageStoreServer;
import com.lld.im.service.utils.MessageProducer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class GroupMessageServer {

    @Autowired
    private CheckChartServer checkChartServer;

    @Autowired
    private MessageProducer messageProducer;

    @Autowired
    private ImGroupMemberService imGroupMemberService;

    @Autowired
    private MessageStoreServer messageStoreServer;

    private  final ThreadPoolExecutor threadPoolExecutor;

     {
        //线程池大小 最大大小 存活时间
        threadPoolExecutor=new ThreadPoolExecutor(8, 8, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000)
                , runnable -> {
            Thread thread = new Thread(runnable);
            //设置线程在后台运行
            thread.setDaemon(true);
            return thread;
        });
    }



    public void process(GroupMessageContent messageContent) {

//        Integer appId = messageContent.getAppId();
//        String fromId = messageContent.getFromId();
        //前置校验
//        ResponseVO responseVO = beforeSendCheck(appId, fromId, messageContent.getGroupId());
//        if (responseVO.isOk()) {
//            try{

        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                //TODO
                // 1.回复ack给发送端
                //TODO 保存群聊消息
                messageContent.setMessageSequence(System.currentTimeMillis());
                messageContent.setMessageTime(System.currentTimeMillis());
                messageStoreServer.storeGroupMessage(messageContent);
                ack(messageContent,ResponseVO.successResponse());
                // TODO 2. IM服务器将数据给发送端的所有在线客户端(数据同步)
                syncSendFromUserAllClient(messageContent);
                //TODo 3. IM服务器将消息分发给群所有成员
                sendMsgToGroupAllUser(messageContent);
            }
        });

//            }catch (Exception e){
                //校验未通过
                // 发送失败 错误ack
//                ack(messageContent, responseVO);
//            }
//        }else {
//            ack(messageContent,responseVO);
//        }
    }

    /**
     * 将消息发送给群成员的所有客户端
     * @param messageContent
     */
    private void sendMsgToGroupAllUser(GroupMessageContent messageContent){
        log.info("message send all toUser client :{}", messageContent.getMessageId());
        List<String> groupMemberId = imGroupMemberService
                .getGroupMemberId(messageContent.getGroupId(), messageContent.getAppId());
        for (String memberId : groupMemberId) {
            messageProducer.sendToAllOnlineUser(memberId, GroupEventCommand.MSG_GROUP,
                    messageContent, messageContent.getAppId());
        }

    }


    /**
     * 将消息同步给发送方的所有客户端
     * @param messageContent
     */
    private void syncSendFromUserAllClient(GroupMessageContent messageContent) {
        log.info("message sync all from client :{}", messageContent.getMessageId());
        messageProducer.sendToUserExceptClient(messageContent.getFromId(),GroupEventCommand.MSG_GROUP
                ,messageContent,messageContent);
    }


    /**
     * ack确认是发给发送方的
     *
     * @param messageContent
     * @param responseVO
     */
    private void ack(GroupMessageContent messageContent, ResponseVO responseVO) {
        log.info("message ack :{}", messageContent.getMessageId());
        log.info("message ack status :{}", responseVO.getCode());
        ChartMessageAckPack chartMessageAckPack = new ChartMessageAckPack();
        chartMessageAckPack.setMessageId(messageContent.getMessageId());
        responseVO.setData(chartMessageAckPack);
        messageProducer.sendToTargetSingleUser(messageContent.getFromId(),
                MessageCommand.MSG_ACK, responseVO, messageContent);
    }

    public ResponseVO checkGroupStatus(Integer appId, String fromId, String groupId) {
        //判断
        ResponseVO responseVO = checkChartServer.checkGroupStatus(appId, groupId,fromId);
        if (!responseVO.isOk()) {
            return responseVO;
        }
       return ResponseVO.successResponse();
    }

}
